/////////////////////////////////////////////////////////////////////////////
/*/	
 *	Creator:		Joshua C. Rouzer
 *	Title:			Particle cpp
 *	Last Edited:	07/08/2013
 *	Summary:		
/*/
/////////////////////////////////////////////////////////////////////////////
#include "CSGD_TextureManager.h"
#include "CSGD_Direct3D.h"
#include "Emitter.h"
#include "Particle.h"
/////////////////////////////////////////////////////////////////////////////
// Function		: Constructor
// Notes		: Assigns provided values to particle variables
/////////////////////////////////////////////////////////////////////////////
CParticle::CParticle(CEmitter *_Owner, float _PosX, float _PosY, float _Life){
	m_bIsAlive = true;
	SetPosX(_PosX);
	SetPosY(_PosY);
	SetVelX(_Owner->GetStVelX());
	SetVelY(_Owner->GetStVelY());
	SetRot(_Owner->GetStRot());
	m_fLife		= _Life;
	m_fScale	= _Owner->GetStScale();
	m_nAlpha	= _Owner->GetStColorA();
	m_nRed		= _Owner->GetStColorR();
	m_nGreen	= _Owner->GetStColorG();
	m_nBlue		= _Owner->GetStColorB();
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Default Constructor
// Notes		: Assigns empty values to a particle
/////////////////////////////////////////////////////////////////////////////
CParticle::CParticle(){
	m_bIsAlive = true;
	SetPosX(0.0f);
	SetPosY(0.0f);
	SetVelX(0.0f);
	SetVelY(0.0f);
	SetRot(0.0f);
	m_fLife = 0.0f;
	m_fScale = 1.0f;
	m_nAlpha = 255;
	m_nRed = 0;
	m_nGreen = 0;
	m_nBlue = 0;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Destructor
// Notes		: Cleans up any dynamically allocated memory
/////////////////////////////////////////////////////////////////////////////
CParticle::~CParticle(){

}
/////////////////////////////////////////////////////////////////////////////
// Function		: Operator ==
// Parameters	: pParticle - The particle to compare to
// Return		: Whether the particles are equal
// Notes		: Checks all variables to see if they match
/////////////////////////////////////////////////////////////////////////////
bool CParticle::operator==(CParticle& pParticle){
	bool _return = true;
	//Check alive status and Life
	if(this->m_bIsAlive != pParticle.m_bIsAlive || this->m_fLife != pParticle.m_fLife){
		_return = false;
	}
	//Check position
	else if(this->GetPosX() != pParticle.GetPosX() || this->GetPosY() != pParticle.GetPosY()){
		_return = false;
	}
	//Check current Info
	else if(this->m_fScale != pParticle.m_fScale || 
		this->GetVelX() != pParticle.GetVelX() || this->GetVelY() != pParticle.GetVelY() ||
		this->GetRot() != pParticle.GetRot()){
		_return = false;
	}
	//Check Color Info.
	else if(this->m_nAlpha != pParticle.m_nAlpha || this->m_nRed != pParticle.m_nRed ||
		this->m_nGreen != pParticle.m_nGreen || this->m_nBlue != pParticle.m_nBlue){
		_return = false;
	}
	return _return;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: Update
// Parameters	: dT - Time elapsed since last update
// Notes		: Updates all variables based on dT
/////////////////////////////////////////////////////////////////////////////
void CParticle::Update(float dT, CEmitter *pOwner){
	if(m_bIsAlive == false){return;}
	//Update Life
	m_fLife -= dT;
	if(m_fLife <= 0.0f){
		m_bIsAlive = false;
		pOwner->Despawn(*this);
		//delete this;
		return;
	}
	//Update the position
	SetPosX(GetPosX() + (m_fVelX * dT));
	SetPosY(GetPosY() + (m_fVelY * dT));
	//Update the velocity
	float off = pOwner->GetLifeMax() - pOwner->GetLifeMin();
	if(!pOwner->GetInvert()){
		SetVelX(GetVelX() + (pOwner->GetEndVelX() - pOwner->GetStVelX()) * (dT / (off != 0 ? off : pOwner->GetLifeMin())));
		SetVelY(GetVelY() + (pOwner->GetEndVelY() - pOwner->GetStVelY()) * (dT / (off != 0 ? off : pOwner->GetLifeMin())));
	}
	else{
		if(GetVelX() == 0.0f && m_fLife >= 0.01){
			SetVelX((pOwner->GetCenterX() - GetPosX()) / (off != 0 ? off : pOwner->GetLifeMin()));
			SetVelY((pOwner->GetCenterY() - GetPosY()) / (off != 0 ? off : pOwner->GetLifeMin()));
		}
		else{
			SetVelX(GetVelX() + ((0.0f - GetVelX()) * (dT / (off != 0 ? off : pOwner->GetLifeMin()))));
			SetVelY(GetVelY() + ((0.0f - GetVelY()) * (dT / (off != 0 ? off : pOwner->GetLifeMin()))));
		}
	}
	//Update the Color
	m_nAlpha = m_nAlpha + (int)((pOwner->GetEndColorA() - pOwner->GetStColorA()) * (dT / m_fLife));
	m_nRed   = m_nRed	+ (int)((pOwner->GetEndColorR() - pOwner->GetStColorR()) * (dT / m_fLife));
	m_nGreen = m_nGreen + (int)((pOwner->GetEndColorG() - pOwner->GetStColorG()) * (dT / m_fLife));
	m_nBlue  = m_nBlue	+ (int)((pOwner->GetEndColorB() - pOwner->GetStColorB()) * (dT / m_fLife));
		//Don't go under
	if(m_nAlpha < 0){m_nAlpha = 0;}
	if(m_nRed	< 0){m_nRed	  = 0;}
	if(m_nGreen < 0){m_nGreen = 0;}
	if(m_nBlue	< 0){m_nBlue  = 0;}
		//Don't go over
	if(m_nAlpha > 255){m_nAlpha = 255;}
	if(m_nRed	> 255){m_nRed   = 255;}
	if(m_nGreen > 255){m_nGreen = 255;}
	if(m_nBlue	> 255){m_nBlue  = 255;}
	//Update the Scale
	m_fScale = m_fScale + (pOwner->GetEndScale() - pOwner->GetStScale()) * (dT /(off != 0 ? off : pOwner->GetLifeMin()));
	//Update the Rotation
	SetRot(GetRot() + (pOwner->GetEndRot() - pOwner->GetStRot()) * (dT / (off != 0 ? off : pOwner->GetLifeMin())));
}